﻿/// ZaxControls
/// Programmed by Leland Ede
/// Website: http://www.zaxisstudios.com
/// E-Mail: codeplex@zaxis-studios.com
/// Create: 4/03/2014
/// Modified: 4/09/2014

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace ZaxLib.Web.UI.WebControls
{
	[DefaultProperty("Text")]
	[ToolboxData("<{0}:DropDownList runat=server></{0}:DropDownList>")]
	public class DropDownList : ZaxControl
	{
		#region Parameters

		[Bindable(false)]
		[Category("Data")]
		[DefaultValue("false")]
		[Description("Single select or multiple selections")]
		[Localizable(true)]
		public String ListItems
		{
			get
			{
				String s = ViewState["ListItems"] as String;
				return (s == null ? String.Empty : s);
			}
			set
			{
				ViewState["ListItems"] = value;
			}
		}

		private ArrayList _items = null;
		public virtual ArrayList Items
		{
			get
			{
				if (_items.Count == 0 && ListItems.Trim().Length > 0)
				{
					String[] items = ListItems.Split(',');
					foreach (String item in items)
					{
						// Add items to the list
						AddItem(item);
					}// End foreach item in items
				}// Endif _items is null

				return _items;
			}// End get
		}// End parameter Items

		[Bindable(false)]
		[Category("Appearance")]
		[DefaultValue("false")]
		[Description("Single select or multiple selections")]
		[Localizable(true)]
		public bool MultiSelect
		{
			get
			{
				bool b = Convert.ToBoolean(ViewState["MultiSelect"]);
				return b;
			}
			set
			{
				ViewState["MultiSelect"] = value;
			}
		}

		[Bindable(false)]
		[Category("Appearance")]
		[DefaultValue("false")]
		[Description("Single select or multiple selections")]
		[Localizable(true)]
		public int Size
		{
			get
			{
				int i = Convert.ToInt32(ViewState["Size"]);
				return i;
			}
			set
			{
				ViewState["Size"] = value;
			}
		}

		#endregion

		#region Constructors

		public DropDownList()
			: base()
		{
			_items = new ArrayList();
		}

		#endregion

		#region Data Structures

		private struct DataNode
		{
			public String label;
			public String value;
			public int id;

			public DataNode(String inLabel, String inValue, int inId = 0)
			{
				label = inLabel;
				value = inValue;
				id = inId;
			}
		}

		#endregion

		#region Render Methods

		protected override void RenderContents(HtmlTextWriter writer)
		{
			HelpPosition = "Right";
			if (MultiSelect)
			{
				HelpPosition = "AfterLabel";
			}
			base.RenderContents(writer);
		}

		#endregion

		#region Control Writers

		/// <summary>
		/// Draw DropDownList main input control
		/// </summary>
		/// <param name="writer"></param>
		protected override void ControlWrite(HtmlTextWriter writer)
		{
			// Call base writer
			base.ControlWrite(writer);
			// Check to see if there are any items in the list for this control
			if (Items.Count > 0)
			{
				// Add the unique ID for control and data binding
				writer.AddAttribute(HtmlTextWriterAttribute.Name, UniqueID);
				// Check if there is a class defined
				if (CssClass.Trim().Length > 0)
				{
					// Add class to parent attribute
					writer.AddAttribute(HtmlTextWriterAttribute.Class, CssClass);
				}// Endif CssClass is not empty
				if (MultiSelect)
				{
					writer.AddAttribute(HtmlTextWriterAttribute.Multiple, "Multiple");
					writer.AddAttribute(HtmlTextWriterAttribute.Size, Size.ToString());
				}
				// Start rendering the select tag
				writer.RenderBeginTag(HtmlTextWriterTag.Select);
				// Clear our writer attributes
				writer.Flush();

				// Convert Text into an array for finding elements
				String[] data = Text.Split(',');
				// Sort array for binary search optimization
				Array.Sort(data);

				// Loop though each element in the Items list
				foreach (DataNode node in Items)
				{
					// Add attributes value
					writer.AddAttribute(HtmlTextWriterAttribute.Value, node.value);
					// Check if item is selected
					if (Array.BinarySearch(data, node.value) >= 0)
					{
						// Item is in value list so make is selected
						writer.AddAttribute(HtmlTextWriterAttribute.Selected, "selected");
					}
					// Start rendering the option tag
					writer.RenderBeginTag(HtmlTextWriterTag.Option);
					// Write the display value
					writer.Write(node.label);
					// Close option tag
					writer.RenderEndTag();
					// Add an extra line for easier reading of the HTML code
					writer.WriteLine();
					// Clear the writers attributes
					writer.Flush();
				}// End foreach loop
				// Draw the end select tag
				writer.RenderEndTag();
			}// Endif Items count is greater than zero
		}// End method ControlWrite

		#endregion

		#region Data Management Methods

		/// <summary>
		/// Add item to drop down list with unique label
		/// </summary>
		/// <param name="label">Label of value item</param>
		/// <param name="value">Valie stored in form</param>
		public void AddItem(String label, String value)
		{
			// Initialize the item list
			int itemId = _items.Count;
			DataNode node = new DataNode(label, value, itemId);
			_items.Add(node);
		}

		/// <summary>
		/// Add item to drop down list with unique label
		/// </summary>
		/// <param name="label">Label of value item</param>
		/// <param name="id">Numeric value of the label</param>
		public void AddItem(String label, int id)
		{
			AddItem(label, id.ToString());
		}

		/// <summary>
		/// Add item to drop down list.  This will store the value and label as the same value.
		/// </summary>
		/// <param name="value">Value to add to list</param>
		public void AddItem(String value)
		{
			int itemId = _items.Count;
			DataNode node = new DataNode(value, value, itemId);
			_items.Add(node);
		}

		#endregion
	}
}
